using System.Collections.Generic;
using System.Linq;
using MvcContrib.Pagination;
using NHibernate.Transform;
using OTE.Contract;
using SharpArch.NHibernate;

namespace OTE.Web.Mvc.Queries.Category
{
    /// <summary>
    /// http://stackoverflow.com/questions/4977038/can-i-use-nhibernate-criteria-to-project-an-entity-and-its-child-collection-onto
    /// </summary>
    public class CategoryQuery : NHibernateQuery, ICategoryQuery
    {
        public IPagination<CategoryDTO> GetPagedList(int page, int size)
        {
            Domain.Category categoryAlias = null;

            var query = Session.QueryOver(() => categoryAlias);

            var count = query.ToRowCountQuery();
            var totalCount = count.FutureValue<int>();

            var firstResult = (page - 1) * size;

            var viewModels = query.TransformUsing(Transformers.DistinctRootEntity)
                                  .List<Domain.Category>()
                                  .Select(x => new CategoryDTO
                                    {
                                        Id = x.Id,
                                        Name = x.Name,
                                        CreatedBy = x.CreatedBy,
                                        CreatedDate = x.CreatedDate,
                                        ModifiedBy = x.ModifiedBy,
                                        ModifiedDate = x.ModifiedDate
                                    })
                                  .Skip(firstResult)
                                  .Take(size)
                                  .ToArray();

            return new CustomPagination<CategoryDTO>(viewModels, page, size, totalCount.Value);
        }

        public IEnumerable<CategoryDTO> GetCategoryParent()
        {
            var parents = from c in Session.QueryOver<Domain.Category>().Future()
                          select new CategoryDTO
                                     {
                                         Id = c.Id,
                                         Name = c.Name,
                                         ParentId = c.Parent == null ? -1 : c.Parent.Id,
                                         CreatedBy = c.CreatedBy,
                                         CreatedDate = c.CreatedDate,
                                         ModifiedBy = c.ModifiedBy,
                                         ModifiedDate = c.ModifiedDate
                                     };

            return parents;
        }

        public CategoryDTO GetCategoryById(int catId)
        {
            Domain.Category categoryAlias = null;

            var cates = Session.QueryOver(() => categoryAlias).List();
            var result = from c in cates
                         where c.Id == catId
                         select new CategoryDTO
                                    {
                                        Id = c.Id,
                                        Name = c.Name,
                                        CreatedBy = c.CreatedBy,
                                        CreatedDate = c.CreatedDate,
                                        ModifiedBy = c.ModifiedBy,
                                        ModifiedDate = c.ModifiedDate,
                                        ParentId = c.Parent != null ? c.Parent.Id : -1
                                    };

            return result.FirstOrDefault();
        }

        public string GetCategoryParentName(int cateId)
        {
            var cat = from c in Session.QueryOver<Domain.Category>().Future<Domain.Category>()
                      //join cc in Session.QueryOver<CategoryContent>().Future<CategoryContent>() on c.Id equals cc.Category.Id
                      where c.Parent != null && c.Id == cateId
                      select c.Parent.Name;

            return cat.FirstOrDefault();
        }

        public CategoryDTO GetCategoryContentByCategoryId(int catId)
        {
            var result = from cc in Session.QueryOver<Domain.Category>().Future<Domain.Category>()
                         where cc.Id == catId
                         select new CategoryDTO
                         {
                             Id = cc.Id,
                             Name = cc.Name
                         }; ;

            return result.FirstOrDefault();
        }

        public IEnumerable<CategoryDTO> GetChildCategory(int cateId)
        {
            var result = from cc in Session.QueryOver<Domain.Category>().Future<Domain.Category>()
                         where cc.Parent != null && cc.Parent.Id == cateId
                         select new CategoryDTO
                         {
                             Id = cc.Id,
                             Name = cc.Name
                         };
            return result;
        }
    }
}